<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  
  <link href="../css/style.css" rel="stylesheet" type="text/css">

</head>
<body>
<h1>4.13. Циклический сдвиг</h1>
<p class="article">
Циклический сдвиг отличается от линейного тем, что выдвигаемые с одного конца биты вдвигаются с другой стороны, то есть движутся по кольцу. В процессора x86 существует 2 вида циклического сдвига: простой и через флаг переноса (CF). У всех команд, рассматриваемых в этой части учебного курса, по 2 операнда, таких же, как у команд линейного сдвига. Первый операнд — сдвигаемое значение и место для записи результата. Второй операнд — счётчик сдвигов, который может находится в регистре CL или указываться непосредственно.
</p>
<h2>Простой циклический сдвиг</h2>
<p class="article">
Циклический сдвиг вправо выполняется командой ROR, а влево — командой ROL. Схема работы этих команд представлена на рисунке (на примере 8-битного операнда):
</p>
<div class="image">
	<img src="../img/4.13_1.png">
	<p>Состояние регистров при циклическом сдвиге</p>
</div>
<p class="article">
Значение последнего выдвигаемого бита копируется в флаг CF. Для сдвигов на 1 бит устанавливается флаг OF, если в результате сдвига изменяется знаковый бит операнда. 
</p>
<pre class="code">
    rol bl,1         ;Циклический сдвиг BL на 1 бит влево
    ror word[si],5   ;Циклический сдвиг слова по адресу в SI на 5 бит вправо
    rol ax,cl        ;Циклический свдиг AX на CL бит влево
</pre>
<div class="notetip">
Большинство компьютеров не могут напрямую адресовать биты, которые содержатся группами по 8, 16, 32 или 64 битов в словах. Для обеспечения работы с битами существует множество машинных инструкций, включающие различные типы сдвигов. 
</div>
<h2>Циклический сдвиг через флаг переноса</h2>
<p class="article">
Отличие от простого циклического сдвига в том, что флаг CF участвует в сдвиге наравне с битами операнда. При сдвиге на 1 бит выдвигаемый бит помещается в CF, а значение CF вдвигается в операнд с другой стороны. При сдвиге на несколько бит эта операция повторяется многократно. Циклический сдвиг через флаг переноса выполняется командами RCR (вправо) и RCL (влево).
</p>
<div class="image">
	<img src="../img/4.13_2.png">
</div>
<p class="article">
Опять же для сдвигов на 1 бит устанавливается флаг OF, если в результате сдвига изменяется знаковый бит операнда. Примеры использования команд:
</p>
<pre class="code">
    rcr dh,3         ;Цикл. сдвиг DH на 3 бита вправо через флаг CF
    rcl byte[bx],cl  ;Цикл. сдвиг байта по адресу в BX на CL бит влево через флаг CF
    rcl dx,1         ;Цикл. сдвиг DX на 1 бит влево через флаг CF
</pre>
<h2>Пример программы</h2>
<p class="article">
В качестве примера напишем программу для подсчёта единичных битов в байте. Для анализа битов используется команда ROL в цикле. Цикл выполняется 8 раз — по числу битов в байте. Если очередной бит равен 1, то выполняем инкремент счётчика единичных битов.
</p>
<pre class="code">
use16             ;Генерировать 16-битный код
org 100h          ;Программа начинается с адреса 100h
 
    mov al,[x]    ;AL = x
    xor bl,bl     ;BL = 0 (Здесь будем считать единичные биты)
    mov cx,8      ;Инициализация счётчика цикла
lp:
    rol al,1      ;Цилический сдвиг AL на 1 бит влево
    jnc bit0      ;Переход, если CF=0
    inc bl        ;Инкремент счетчика единичных битов
bit0:
    loop lp       ;Команда цикла
    mov [n],bl    ;Сохраняем результат в n
 
    mov ax,4C00h  ;\
    int 21h       ;/ Завершение программы
;----------------------------------------------------------------------
x  db 89h         ;Байт
n  db ?           ;Количество единичных битов в байте
</pre>

</body>
</html>
